#include "StockCallPutCombinations.h"

#include "CallPutPair.h"

namespace
{
    const std::size_t vecMax = 100;
}

StockCallPutCombinations::StockCallPutCombinations( const std::string& separator, const std::string& stockId )
: m_separator( separator ),
  m_stockId( stockId ),
  m_calls(),
  m_puts()
{
    m_calls.reserve( vecMax );
    m_puts.reserve( vecMax );
}

void StockCallPutCombinations::AddWarrant( const Warrant& warrant )
{
    if( m_stockId != warrant.m_stockId )
        throw std::invalid_argument( __FUNCTION__ " warrant with unexpected stock id " );

    if( warrant.m_type == Warrant::call )
        m_calls.push_back( warrant );
    else if( warrant.m_type == Warrant::put )
        m_puts.push_back( warrant );
}

void StockCallPutCombinations::PrintCombinations( std::ofstream& outputFile )
{
    for( std::vector<Warrant>::const_iterator callIterator = m_calls.begin();
         callIterator != m_calls.end(); ++callIterator )
    {
        for( std::vector<Warrant>::const_iterator putIterator = m_puts.begin();
             putIterator != m_puts.end(); ++putIterator )
        {
            CallPutPair callPutPair( *callIterator, *putIterator );
            printRowToFile( outputFile,
                            m_stockId, callIterator->m_id, putIterator->m_id,
                            callPutPair.GetCost(),
                            callPutPair.GetRangeStart(),
                            callPutPair.GetRangeEnd(),
                            callPutPair.GetRangeEnd() - callPutPair.GetRangeStart() );
        }
    }

}

void StockCallPutCombinations::printRowToFile(
        std::ofstream& outputFile,
        std::string     stockId,
        std::string     callId,
        std::string     putId,
        double          cost,
        double          rangeStart,
        double          rangeEnd,
        double          rangeDiff
        )
{
    outputFile
        << stockId << m_separator
        << callId << m_separator
        << putId << m_separator
        << cost << m_separator
        << rangeStart << m_separator
        << rangeEnd << m_separator
        << rangeDiff << m_separator
        << std::endl;
}

void StockCallPutCombinations::PrintFirstRow( const std::string& separator, std::ofstream& outputFile )
{
    outputFile
        << "Stock ID" << separator
        << "Call ID" << separator
        << "Put Id" << separator
        << "Cost" << separator
        << "Range Start" << separator
        << "Range End" << separator
        << "Range Different" << separator
        << std::endl;
}